package cn.hchaojie.boot.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
	@Autowired
	private JwtTokenProvider tokenProvider;
	
	@Autowired
	private UserDetailsService userDetailsService;

	@Override
	protected void doFilterInternal(
			HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		// 从请求头里面解析出来jwt token
		// eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3YW5nd3UiLCJleHAiOjE1Mzg0NDc2MTcsImlhdCI6MTUzODQ0NzAxMn0.iCR1H2MFLkTasfIj8adR0BxqKXDibZK-T7uX1sCjvY0
		String token = tokenProvider.extractToken(request);
		
		if (tokenProvider.validate(token)) {	// 验证token的合法性
			//解析token， 取用户名
			String userName = tokenProvider.getUserNameFromToken(token);
			
			// 从数据库里面，根据用户名查用户信息
			UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
			
			// 生成认证信息
			UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
					userDetails, null, userDetails.getAuthorities());
			authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
			
			// 把认证信息存入SecurityContextHolder，后续其它的过滤器会取这个认证信息
			// 如果取不到，就会报认证失败
			SecurityContextHolder.getContext().setAuthentication(authentication);
		}

		
		filterChain.doFilter(request, response);
	}
}
